package com.youlu.campus.service.activity;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.base.exception.QaMaxLimitException;
import com.youlu.campus.base.interactive.vo.ActivitySignUpRequest;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.QaCommitCommand;
import com.youlu.campus.entity.VO.res.QaInfoScoreResponse;
import com.youlu.campus.entity.VO.res.QaRuleMatchRes;
import com.youlu.campus.entity.VO.res.UserJoinActivityRes;
import com.youlu.campus.entity.ca.UserCa;
import com.youlu.campus.entity.commission.UserParticipateDistributorChannelInfo;
import com.youlu.campus.entity.course.ActivityCourse;
import com.youlu.campus.entity.english.UserCompetitionQaAnswer;
import com.youlu.campus.entity.english.UserQaAnswerLog;
import com.youlu.campus.entity.english.UserQuestionInfo;
import com.youlu.campus.entity.english.vo.response.UserQaScoreResponse;
import com.youlu.campus.entity.enums.ActivityVideoStatusEnum;
import com.youlu.campus.service.ca.UserCaService;
import com.youlu.campus.service.commission.UserParticipateDistributorChannelInfoService;
import com.youlu.campus.service.course.UserVideoService;
import com.youlu.campus.service.english.CompetitionQaInfoService;
import com.youlu.campus.service.platform.PointPlatformConfigService;
import com.youlu.campus.service.qa.UserCompetitionQaAnswerService;
import com.youlu.campus.service.qa.UserQaInfoService;
import com.youlu.campus.service.qa.impl.UserQaInfoServiceImpl;
import com.youlu.campus.service.qa.impl.UserQaRankingService;
import com.youlu.campus.service.visitor.UserInfoExtendService;
import com.youlu.campus.service.visitor.UserPointsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WechatMiniQaService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserVideoService userVideoService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;

    @Autowired
    private UserQaInfoService userQaInfoService;

    @Autowired
    public CompetitionQaInfoService competitionQaInfoService;

    @Autowired
    private UserCaService userCaService;

    @Autowired
    private UserCompetitionQaAnswerService userCompetitionQaAnswerService;

    @Autowired
    private UserPointsService userPointsService;

    @Autowired
    private UserInfoExtendService userInfoExtendService;

    @Autowired
    private PointPlatformConfigService pointPlatformConfigService;

    @Autowired
    private UserQaRankingService userQaRankingService;

    @Autowired
    private UserParticipateDistributorChannelInfoService userParticipateDistributorChannelInfoService;

    public Map<String, String> getUserCaReceiveQrCode(String appId) {
        Map<String, String> result = new HashMap<>(1);
        PointPlatformConfig pointPlatformConfig = pointPlatformConfigService.find(appId);
        if (Objects.isNull(pointPlatformConfig)) {
            result.put("caTips", "");
            return result;
        }
        result.put("caTips", pointPlatformConfig.getCaTips());
        return result;


    }

    /**
     * 校验用户答题次数
     *
     * @param currentUser
     * @param activityId
     * @param qaInfoId
     */
    public void checkUserQaLimit(UserPO currentUser, String activityId, String qaInfoId) {
        log.info("【答题】currentUser - > {} | activityId- > {} | qaInfoId- >{}", currentUser.getId(), activityId,
                qaInfoId);
        ActivityQaInfo activityQaInfo = this.mongoTemplate.findById(qaInfoId, ActivityQaInfo.class);
        if (Objects.isNull(activityQaInfo)) {
            throw new BusinessException("当前答题信息不存在");
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(currentUser.getId()));
        query.addCriteria(Criteria.where("activityQaInfoId").is(qaInfoId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        UserQaInfo userQaInfo = this.mongoTemplate.findOne(query, UserQaInfo.class);
        if (Objects.isNull(userQaInfo)) {
            return;
        }
        if (userQaInfo.getReTryQaNum() >= userQaInfo.getTotalQaNum()) {
            log.error("【答题限制】userId-> {} | qaInfoId - > {}| currentQaNum - > {} |totalQaNum - > {}",
                    currentUser.getId(), userQaInfo.getReTryQaNum(), userQaInfo.getTotalQaNum());
            throw new QaMaxLimitException("免费答题次数已用完，可使用200积分兑换一次答题机会。\n" +
                    "\n" +
                    "\n" +
                    "\n" +
                    "注：积分可在“我的”页面，通过完成任务增加。");
        }
    }

    /**
     * 用户积分兑换答题次数
     *
     * @param currentUser
     * @param activityId
     * @param qaInfoId
     */
    public void userPointsExchangeQaCount(UserPO currentUser, String activityId, String qaInfoId) {
        log.info("【积分兑换答题次数】currentUser - > {} | activityId- > {} | qaInfoId- >{}", currentUser.getId(), activityId,
                qaInfoId);
        String lockKey = String.format("campus:qa:exchange-point:activityId:%s:userId:%s", activityId,
                currentUser.getId());
        Boolean existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 3L, TimeUnit.SECONDS);
        if (Objects.nonNull(existKey) && !existKey) {
            log.warn("【积分兑换答题次数】重复提交 userId -> {}| activityId - > {}|qaInfoId - >{}", currentUser.getId(), activityId
                    , qaInfoId);
            return;
        }
        Integer points = 0;
        UserPoints userPoints = userPointsService.findByUserInfo(currentUser);
        if (Objects.nonNull(userPoints)) {
            points = userPoints.getPoint();
        }
        if (points < 200) {
            log.error("【积分兑换答题次数不足】userId -> {}| currentPoints - > {}", currentUser.getId(), points);
            throw new BusinessException("对不起，积分不足200，请先去个人中心完成任务增加积分。");
        }
        Date now = new Date();
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(currentUser.getId()));
        query.addCriteria(Criteria.where("activityQaInfoId").is(qaInfoId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        Update update = new Update();
        update.inc("totalQaNum", 1);
        update.inc("buyQaNum", 1);
        update.set("updatedTime", now);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        UserQaInfo userQaInfoModify = this.mongoTemplate.findAndModify(query, update, findAndModifyOptions,
                UserQaInfo.class);
        if (Objects.isNull(userQaInfoModify)) {
            return;
        }
        //扣减用户积分
        UserPointsDetail userPointsDetail = new UserPointsDetail();
        userPointsDetail.setUserId(currentUser.getId());
        userPointsDetail.setOptDate(now);
        userPointsDetail.setAction("sub");
        userPointsDetail.setBizType("point-exchange-qa");
        userPointsDetail.setBizDesc("积分兑换答题次数");
        userPointsDetail.setComments("积分兑换答题次数");
        userPointsDetail.setPoints(200);
        userPointsDetail.setAppId(currentUser.getAppId());
        userPointsDetail.setPlatform(currentUser.getCurrentPlatform());
        userPointsService.subPoint(userPointsDetail);
    }

    public UserQaScoreResponse doQaCommit(QaCommitCommand qaCommitCommand) {
        UserPO currentUser = qaCommitCommand.getCurrentUser();
        String userId = currentUser.getId();
        String qaInfoId = qaCommitCommand.getQaInfoId();
        log.info("【答题提交】currentUser - > {} |  qaInfoId- >{}", currentUser.getId(), qaInfoId);
        Boolean existLockKey =
                redisTemplate.opsForValue().setIfAbsent(String.format(UserQaInfoServiceImpl.USER_QA_LOCK, userId,
                                qaInfoId),
                        "1", 4L, TimeUnit.SECONDS);
        if (Objects.nonNull(existLockKey) && !existLockKey) {
            log.error("【答题提交重复提交】currentUser - > {} |  qaInfoId- >{}", currentUser.getId(), qaInfoId);
            throw new BusinessException("对不起哦，服务繁忙,稍后重试");
        }
        ActivityQaInfo activityQaInfo = this.mongoTemplate.findById(qaInfoId, ActivityQaInfo.class);
        if (Objects.isNull(activityQaInfo)) {
            throw new BusinessException("不存在该题库信息");
        }
        String activityId = activityQaInfo.getActivityId();
        //校验好答题次数
        this.checkUserQaLimit(currentUser, activityId, qaInfoId);
        ActivityInfo activityInfo = activityService.findOne(activityId);
        //只有视频类行
        Integer courseStatus = 0;
        if ("video".equals(activityInfo.getType())) {
            ActivityCourse activityCourse = mongoTemplate.findById(activityInfo.getCourseId(), ActivityCourse.class);
            if (Objects.isNull(activityCourse)) {
                throw new BusinessException("课程信息不存在");
            }
            courseStatus = userVideoService.getActivityStatus(userId, currentUser.getAppId(), activityId);
            log.info("【答题-课程状态】获取用户购买课程状态 currentUser - > {} |  courseStatus- >{}", userId, courseStatus);
            if (courseStatus < ActivityVideoStatusEnum.DO_THE_TITLE.getType()) {
                log.error("【不满足答题-课程状态】 currentUser - > {} |  courseStatus- >{} | activityId -> {}", userId,
                        courseStatus
                        , activityId);
                throw new BusinessException("对不起，不满足考试答题");
            }
        }

        UserParticipateActivityInfo userParticipateActivityInfo =
                userParticipateActivityInfoService.findByUserIdActivityId(userId, activityId);
        if (Objects.isNull(userParticipateActivityInfo)) {
            throw new BusinessException("未报名，不能参与答题");
        }
        //用户提交答题
        List<ActivityQuestionInfo> userAnswersQuestionInfoList = qaCommitCommand.getUserAnswersQuestionInfoList();
        List<String> userSubmitQuestionIdList =
                userAnswersQuestionInfoList.stream().map(userAnswer -> userAnswer.getId()).collect(Collectors.toList());
        List<ActivityQuestionInfo> questionInfoList = userQaInfoService.queryQaInfoId(qaInfoId,
                userSubmitQuestionIdList);
        QaInfoScoreResponse userQaInfoScore = competitionQaInfoService.getQaScore(currentUser.getId(), qaInfoId,
                questionInfoList, userAnswersQuestionInfoList);
        Double qaScore = userQaInfoScore.getQaScore();
        userQaInfoScore.clear();
        Date now = new Date();
        Query query = userQaInfoService.getQaQuery(userId, qaInfoId, activityId);
        Update update = new Update();
        //是否第一次答题
        Boolean qaInvite = Boolean.FALSE;
        UserQaInfo existsUserQaInfo = this.mongoTemplate.findOne(query, UserQaInfo.class);
        if (Objects.isNull(existsUserQaInfo)) {
            update.set("createdTime", now);
            update.set("totalQaNum", activityQaInfo.getTotalQaNum());
            update.set("qaScore", qaScore);
            update.set("buyQaNum", 0);
            qaInvite = Boolean.TRUE;
        } else {
            if (Objects.nonNull(existsUserQaInfo) && qaScore.compareTo(existsUserQaInfo.getQaScore()) == 1) {
                update.set("qaScore", qaScore);
            }
            if (existsUserQaInfo.getBuyQaNum() <= 0) {
                update.set("buyQaNum", 0);
            }
        }
        if (qaScore.intValue() >= activityQaInfo.getPassQaScore().intValue()) {
            update.set("passed", Boolean.TRUE);
        }
        update.push("scoreSet", qaScore);
        update.set("updatedTime", now);
        update.set("activityQaInfoId", qaInfoId);

        update.set("activityName", activityInfo.getName());
        update.inc("reTryQaNum", 1);
        update.set("no", activityQaInfo.getNo());
        log.info("【答题提交- 得分 】currentUser - > {} | qaInfoId->{} |qaScore -> {}", currentUser.getId(), qaInfoId, qaScore);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        UserQaInfo userQaInfo = this.mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserQaInfo.class);
        UserQaScoreResponse userQaScore = new UserQaScoreResponse();
        userQaScore.setQaInfoId(qaInfoId);
        userQaScore.setQaScore(qaScore.intValue());
        userQaScore.setActivityId(activityId);
        userQaScore.setScore("得分：" + qaScore.intValue() + "分");
        //答题初赛才算邀请成功
        if (qaInvite && ("wx-mini-dreambeat-contest".equals(activityInfo.getType()) || "douyin".equals(activityInfo.getType()))) {
            if (1 == activityQaInfo.getNo()) {
                if (StringUtils.isBlank(userParticipateActivityInfo.getActivityChannelId())) {
                    log.info("【邀请成功更新】currentUser - > {} | activityId->{}", currentUser.getId(), activityId);
                    ActivitySignUpRequest request = new ActivitySignUpRequest();
                    request.setActivityId(activityId);
                    request.setPlatform(currentUser.getCurrentPlatform());
                    request.setAppId(currentUser.getAppId());
                    request.setUserId(currentUser.getId());
                    activityService.extSignUpActivity(request, currentUser);
                }
            }
        }
        Double qaScoreDB = userQaInfo.getQaScore();
        if (Objects.isNull(qaScoreDB) || qaScoreDB.intValue() == 0) {
            qaScoreDB = qaScore;
        }
        if (activityQaInfo.getNo() == 1) {//校赛
            userParticipateActivityInfo.setQaScore(qaScoreDB);
        } else if (activityQaInfo.getNo() == 2) {//省赛
            userParticipateActivityInfo.setProvinceQaScore(qaScoreDB);
        } else {//国赛
            userParticipateActivityInfo.setCountryQaScore(qaScoreDB);
        }
        UserInfoExtend userInfoExtend = userInfoExtendService.findByUserIdAndAppId(currentUser);
        if (Objects.nonNull(userInfoExtend)) {
            if (StringUtils.isNotBlank(userInfoExtend.getUniversityId())) {
                userParticipateActivityInfo.setUniversityId(userInfoExtend.getUniversityId());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getUniversityName())) {
                userParticipateActivityInfo.setUniversityName(userInfoExtend.getUniversityName());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getName())) {
                userParticipateActivityInfo.setName(userInfoExtend.getName());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getMobile())) {
                userParticipateActivityInfo.setMobile(userInfoExtend.getMobile());
            }
        }
        userParticipateActivityInfo.setPassed(userQaInfo.getPassed());
        this.userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
        if (Objects.nonNull(userParticipateActivityInfo) && StringUtils.isNotBlank(userParticipateActivityInfo.getActivityChannelId())) {//渠道报名更新
            UserParticipateDistributorChannelInfo updateDistributorChannelInfo = new UserParticipateDistributorChannelInfo();
            updateDistributorChannelInfo.setId(null);
            updateDistributorChannelInfo.setUserId(userParticipateActivityInfo.getUserId());
            updateDistributorChannelInfo.setActivityId(userParticipateActivityInfo.getActivityId());
            updateDistributorChannelInfo.setQaScore(userParticipateActivityInfo.getQaScore());
            updateDistributorChannelInfo.setProvinceQaScore(userParticipateActivityInfo.getProvinceQaScore());
            updateDistributorChannelInfo.setCountryQaScore(userParticipateActivityInfo.getCountryQaScore());
            updateDistributorChannelInfo.setName(userParticipateActivityInfo.getName());
            updateDistributorChannelInfo.setMobile(userParticipateActivityInfo.getMobile());
            updateDistributorChannelInfo.setUniversityId(userParticipateActivityInfo.getUniversityId());
            updateDistributorChannelInfo.setUniversityName(userParticipateActivityInfo.getUniversityName());
            updateDistributorChannelInfo.setActivityChannelId(userParticipateActivityInfo.getActivityChannelId());
            userParticipateDistributorChannelInfoService.save(updateDistributorChannelInfo);
        }
        //记录用户答题
        UserQaAnswerLog userQaLog = new UserQaAnswerLog();
        userQaLog.setAnswersQuestionInfoList(qaCommitCommand.getUserAnswersQuestionInfoList());
        userQaLog.setUserId(currentUser.getId());
        userQaLog.setQaInfoId(qaInfoId);
        userQaLog.setScore(qaScore);
        userQaLog.setName(userParticipateActivityInfo.getName());
        userQaLog.setUniversityId(userParticipateActivityInfo.getUniversityId());
        userQaLog.setUniversityName(userParticipateActivityInfo.getUniversityName());
        userQaLog.setActivityId(activityQaInfo.getActivityId());
        this.mongoTemplate.save(userQaLog);
        if (Objects.isNull(userQaInfo) || qaScore.intValue() == 0 || qaScore.intValue() < activityQaInfo.getPassQaScore().intValue()) {
            log.warn("【答题提交- 得分未通过】currentUser - > {} | qaInfoId->{} |qaScore -> {}", currentUser.getId(), qaInfoId,
                    qaScore);
            userQaScore.setTipsScore("很遗憾！暂不能获得证书");
            userQaScore.setButtonText("重新答题");
            userQaScore.setQaErrorCount(userQaInfoScore.getQaErrorCount());
            userQaScore.setQaRightCount(userQaInfoScore.getQaRightCount());
            userQaScore.setRestQa(Boolean.TRUE);
            return userQaScore;
        }
        userQaScore.setHasPaperCa(activityInfo.getHasPaperCa());
        userQaScore.setHasElectronicCa(activityInfo.getHasElectronicCa());
        userQaScore.setDigitalCaReceive(activityInfo.getDigitalCaReceive());
        userQaScore.setDigitalCaNoReceiveDesc(activityInfo.getDigitalCaNoReceiveDesc());
        QaRuleMatchRes qaRuleMatchRes = competitionQaInfoService.qaRuleByQaInfoId(qaInfoId, qaScore);
        String caLevelName = qaRuleMatchRes.getCaLevelName();
        log.info("【答题提交- 得分获取到证书等级】currentUser - > {} | qaInfoId->{} |qaScore -> {} | level -> {}", userId, qaInfoId,
                qaScore, caLevelName);
        UserQaLevel userQaLevel = new UserQaLevel();
        userQaLevel.setActivityQaInfoId(activityQaInfo.getId());
        userQaLevel.setQaNumber(activityQaInfo.getNo());
        userQaLevel.setQsScore(qaScore);
        userQaLevel.setLevel(caLevelName);
        if (CollectionUtils.isNotEmpty(userQaInfo.getUserQaLevelList())) {
            userQaInfo.getUserQaLevelList().add(userQaLevel);
        } else {
            userQaInfo.setUserQaLevelList(Arrays.asList(userQaLevel));
        }
        userQaInfo.setUpdatedTime(now);
        userQaInfo.setCaName(caLevelName);

        this.mongoTemplate.save(userQaInfo);

        UserQaLevel userQaLevel1 =
                userQaInfo.getUserQaLevelList().stream().max(Comparator.comparing(UserQaLevel::getQsScore)).get();
        if (Objects.nonNull(userQaLevel1)) {
            userParticipateActivityInfo.setContestCaName(userQaLevel1.getLevel());
        }


        UserCa userCa = new UserCa();
        Optional<CertificateActivityConfig> certificateActivityConfigOptional =
                userQaInfoService.getCertificateActivityConfig(5, activityQaInfo, activityInfo);
        if (certificateActivityConfigOptional.isPresent()) {
            CertificateActivityConfig certificateActivityConfig = certificateActivityConfigOptional.get();
            userCa.setCertificateActivityConfigId(certificateActivityConfig.getId());
            userCa.setCertificateName(certificateActivityConfig.getCertificateName());
            userCa.setCaType(certificateActivityConfig.getCaType());
            userQaScore.setCaType(certificateActivityConfig.getCaType());
        }
        userCa.setCaLevel(caLevelName);
        userCa.setActivityId(activityId);
        userCa.setMoneyType("3");
        userCa.setActivityName(activityInfo.getName());
        userCa.setTaskBizType("qa");
        userCa.setUserId(userId);
        userCa.setScore(qaScore);
        if (Objects.nonNull(userParticipateActivityInfo)) {
            userCa.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userCa.setUniversityName(userParticipateActivityInfo.getUniversityName());
            userCa.setName(userParticipateActivityInfo.getName());
            userCa.setMobile(userParticipateActivityInfo.getMobile());
            userCa.setGrade(userParticipateActivityInfo.getGrade());
        }
        userCa.setPlatform(currentUser.getCurrentPlatform());
        userCa.setAppId(currentUser.getAppId());
        //生成用户证书信息
        userCaService.create(userCa);
        if (activityInfo.getContestDigitalCaFee() > 0) {
            userQaScore.setDigitalCaPay(Boolean.TRUE);
        }
        userQaScore.setTipsScore("恭喜获得" + caLevelName);
        userQaScore.setQaErrorCount(userQaInfoScore.getQaErrorCount());
        userQaScore.setQaRightCount(userQaInfoScore.getQaRightCount());
        userQaScore.setCaLevel(caLevelName);
        userQaScore.setCaReceive(Boolean.TRUE);
        userQaScore.setDigitalCaPayDesc(activityInfo.getDigitalCaPayDesc());
        if (!userParticipateActivityInfo.checkUserInfo()) {
            userQaScore.setCaUserInfo(Boolean.TRUE);
        }
        if (!"wechat-mini".equals(currentUser.getCurrentPlatform())) {
            //记录用户答题
            UserCompetitionQaAnswer userCompetitionQa = new UserCompetitionQaAnswer();
            userCompetitionQa.setName(userParticipateActivityInfo.getName());
            userCompetitionQa.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userCompetitionQa.setUniversityName(userParticipateActivityInfo.getUniversityName());
            userCompetitionQa.setAnswersQuestionInfoList(userAnswersQuestionInfoList);
            userCompetitionQa.setQaInfoId(qaInfoId);
            userCompetitionQa.setUserId(currentUser.getId());
            userCompetitionQa.setScore(qaScore);
            userCompetitionQa.setActivityGroupId(activityQaInfo.getActivityId());
            userCompetitionQaAnswerService.saveOrUpdate(userCompetitionQa);
        }

        //移除随机生成答题
        this.mongoTemplate.remove(query, UserQuestionInfo.class);
        if ("video".equals(activityInfo.getType())) {
            //维护变更用户流程状态
            userVideoService.updateStatusUserActivityCourse(currentUser, activityId, qaInfoId, courseStatus,
                    (courseStatus >= ActivityVideoStatusEnum.DO_THE_TITLE.getType()) ?
                            ActivityVideoStatusEnum.RECEIVE_CERTIFICATE.getType() :
                            ActivityVideoStatusEnum.DO_THE_TITLE.getType());
        }
        //增加用户分数
        UserQaRanking userQaRanking = new UserQaRanking();
        userQaRanking.setActivityId(activityQaInfo.getActivityId());
        userQaRanking.setQaInfoId(qaInfoId);
        userQaRanking.setQaNo(activityQaInfo.getNo());
        userQaRanking.setHeadImageUrl(currentUser.getAvatarUrl());
        userQaRanking.setUserId(userId);
        userQaRanking.setQaScore(qaScore);
        userQaRanking.setNickName(currentUser.getNickName());
        userQaRanking.setQaTitle(activityQaInfo.getName());
        if (Objects.nonNull(userParticipateActivityInfo)) {
            userQaRanking.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userQaRanking.setUniversityName(userParticipateActivityInfo.getUniversityName());
        }
        this.userQaRankingService.saveOrUpdate(userQaRanking);
        return userQaScore;
    }

    /**
     * 用户报名成功更新报名信息和 可以做表信息
     *
     * @param activityId
     * @param currentUser
     */
    @Async
    public void updateAfterSignUpUserInfo(String activityId, UserPO currentUser) {
        log.info("【报名成功更新用户报名信息】-> activityId - > {},userId- > {}", activityId, currentUser);
        UserParticipateActivityInfo saveSignUpUser = new UserParticipateActivityInfo();
        saveSignUpUser.setUserId(currentUser.getId());
        saveSignUpUser.setActivityId(activityId);
        saveSignUpUser.setMobile(currentUser.getMobile());
        saveSignUpUser.setNickName(currentUser.getNickName());
        saveSignUpUser.setName(currentUser.getName());
        saveSignUpUser.setJoined(Boolean.TRUE);
        saveSignUpUser.setAppId(currentUser.getAppId());
        saveSignUpUser.setPlatform(currentUser.getCurrentPlatform());
        saveSignUpUser.setUniversityId(currentUser.getUniversityId());
        saveSignUpUser.setUniversityName(currentUser.getUniversityName());
        saveSignUpUser.setOpenId(currentUser.getOpenId());
        saveSignUpUser.setUnionId(currentUser.getUnionId());
        //是否来源与音频报名
        saveSignUpUser.setSignUpVideo(currentUser.getSignUpVideo());
        UserInfoExtend userInfoExtend = userInfoExtendService.findUserInfoByUserId(currentUser);
        if (Objects.nonNull(userInfoExtend)) {
            if (StringUtils.isBlank(saveSignUpUser.getMobile())) {
                saveSignUpUser.setMobile(userInfoExtend.getMobile());
            }
            if (StringUtils.isBlank(saveSignUpUser.getNickName())) {
                saveSignUpUser.setNickName(userInfoExtend.getNickName());
            }
            if (StringUtils.isBlank(saveSignUpUser.getUniversityId())) {
                saveSignUpUser.setUniversityId(userInfoExtend.getUniversityId());
            }
            if (StringUtils.isBlank(saveSignUpUser.getUniversityName())) {
                saveSignUpUser.setUniversityName(userInfoExtend.getUniversityName());
            }
            if (StringUtils.isBlank(saveSignUpUser.getName())) {
                saveSignUpUser.setName(userInfoExtend.getName());
            }
        }
        if (StringUtils.isBlank(saveSignUpUser.getName()) || StringUtils.isBlank(saveSignUpUser.getUniversityId()) || StringUtils.isBlank(saveSignUpUser.getUniversityName())) {
            UserParticipateActivityInfo joinActivityUser =
                    userParticipateActivityInfoService.findJoinedUserByUserId(currentUser.getId());
            if (Objects.nonNull(joinActivityUser)) {
                if (StringUtils.isBlank(joinActivityUser.getName())) {
                    saveSignUpUser.setName(joinActivityUser.getName());
                }
                if (StringUtils.isBlank(joinActivityUser.getUniversityId())) {
                    saveSignUpUser.setUniversityId(joinActivityUser.getUniversityId());
                }
                if (StringUtils.isBlank(joinActivityUser.getUniversityName())) {
                    saveSignUpUser.setUniversityName(joinActivityUser.getUniversityName());
                }
            }
        }
        saveSignUpUser.setActivityChannelId(currentUser.getActivityChannelId());
        userParticipateActivityInfoService.saveOrUpdate(saveSignUpUser);
        if (StringUtils.isNotBlank(currentUser.getActivityChannelId())) {
            if (StringUtils.isNotBlank(currentUser.getActivityChannelId())) {
                UserParticipateDistributorChannelInfo updateDistributorChannelInfo = new UserParticipateDistributorChannelInfo();
                BeanUtils.copyProperties(saveSignUpUser, updateDistributorChannelInfo);
                updateDistributorChannelInfo.setId(null);
                updateDistributorChannelInfo.setActivityChannelId(currentUser.getActivityChannelId());
                userParticipateDistributorChannelInfoService.save(updateDistributorChannelInfo);
            }
        }


    }

    /**
     * 导入答题
     *
     * @param qaCommitCommand
     * @return
     */
    public UserQaScoreResponse importQaCommit(QaCommitCommand qaCommitCommand) {
        log.info(":>>> 开始导入答题:{}", JSON.toJSON(qaCommitCommand));
        UserPO currentUser = qaCommitCommand.getCurrentUser();
        String userId = currentUser.getId();
        String qaInfoId = qaCommitCommand.getQaInfoId();
        log.info("【答题提交】currentUser - > {} |  qaInfoId- >{}", currentUser.getId(), qaInfoId);
        Boolean existLockKey =
                redisTemplate.opsForValue().setIfAbsent(String.format(UserQaInfoServiceImpl.USER_QA_LOCK, userId,
                                qaInfoId),
                        "1", 4L, TimeUnit.SECONDS);
        if (Objects.nonNull(existLockKey) && !existLockKey) {
            log.error("【答题提交重复提交】currentUser - > {} |  qaInfoId- >{}", currentUser.getId(), qaInfoId);
            throw new BusinessException("对不起哦，服务繁忙,稍后重试");
        }
        ActivityQaInfo activityQaInfo = this.mongoTemplate.findById(qaInfoId, ActivityQaInfo.class);
        if (Objects.isNull(activityQaInfo)) {
            log.error(":>>> 题库不存在:{}",qaInfoId);
            throw new BusinessException("不存在该题库信息");
        }
        String activityId = activityQaInfo.getActivityId();
        ActivityInfo activityInfo = activityService.findOne(activityId);
        //只有视频类行
        Integer courseStatus = 0;
        if ("video".equals(activityInfo.getType())) {
            ActivityCourse activityCourse = mongoTemplate.findById(activityInfo.getCourseId(), ActivityCourse.class);
            if (Objects.isNull(activityCourse)) {
                throw new BusinessException("课程信息不存在");
            }
            courseStatus = userVideoService.getActivityStatus(userId, currentUser.getAppId(), activityId);
            log.info("【答题-课程状态】获取用户购买课程状态 currentUser - > {} |  courseStatus- >{}", userId, courseStatus);
            if (courseStatus < ActivityVideoStatusEnum.DO_THE_TITLE.getType()) {
                log.error("【不满足答题-课程状态】 currentUser - > {} |  courseStatus- >{} | activityId -> {}", userId,
                        courseStatus
                        , activityId);
                throw new BusinessException("对不起，不满足考试答题");
            }
        }

        UserParticipateActivityInfo userParticipateActivityInfo =
                userParticipateActivityInfoService.findByUserIdActivityId(userId, activityId);
        if (Objects.isNull(userParticipateActivityInfo)) {
            log.error(":>>> 用户未报名:{}.{}",userId, activityId);
            throw new BusinessException("未报名，不能参与答题");
        }
        Double qaScore = qaCommitCommand.getQaScore();
        Date now = new Date();
        Query query = userQaInfoService.getQaQuery(userId, qaInfoId, activityId);
        Update update = new Update();
        //是否第一次答题
        Boolean qaInvite = Boolean.FALSE;
        UserQaInfo existsUserQaInfo = this.mongoTemplate.findOne(query, UserQaInfo.class);
        if (Objects.isNull(existsUserQaInfo)) {
            update.set("createdTime", now);
            update.set("totalQaNum", activityQaInfo.getTotalQaNum());
            update.set("qaScore", qaScore);
            update.set("buyQaNum", 0);
            qaInvite = Boolean.TRUE;
        } else {
            if (Objects.nonNull(existsUserQaInfo) && qaScore.compareTo(existsUserQaInfo.getQaScore()) == 1) {
                update.set("qaScore", qaScore);
            }
            if (existsUserQaInfo.getBuyQaNum() <= 0) {
                update.set("buyQaNum", 0);
            }
        }
        if (qaScore.intValue() >= activityQaInfo.getPassQaScore().intValue()) {
            update.set("passed", Boolean.TRUE);
        }
        update.push("scoreSet", qaScore);
        update.set("updatedTime", now);
        update.set("activityQaInfoId", qaInfoId);

        update.set("activityName", activityInfo.getName());
        update.inc("reTryQaNum", 1);
        update.set("no", activityQaInfo.getNo());
        log.info("【答题提交- 得分 】currentUser - > {} | qaInfoId->{} |qaScore -> {}", currentUser.getId(), qaInfoId, qaScore);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        UserQaInfo userQaInfo = this.mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserQaInfo.class);
        UserQaScoreResponse userQaScore = new UserQaScoreResponse();
        userQaScore.setQaInfoId(qaInfoId);
        userQaScore.setQaScore(qaScore.intValue());
        userQaScore.setActivityId(activityId);
        userQaScore.setScore("得分：" + qaScore.intValue() + "分");
        //答题初赛才算邀请成功
        if (qaInvite && ("wx-mini-dreambeat-contest".equals(activityInfo.getType()) || "douyin".equals(activityInfo.getType()))) {
            if (1 == activityQaInfo.getNo()) {
                if (StringUtils.isBlank(userParticipateActivityInfo.getActivityChannelId())) {
                    log.info("【邀请成功更新】currentUser - > {} | activityId->{}", currentUser.getId(), activityId);
                    ActivitySignUpRequest request = new ActivitySignUpRequest();
                    request.setActivityId(activityId);
                    request.setPlatform(currentUser.getCurrentPlatform());
                    request.setAppId(currentUser.getAppId());
                    request.setUserId(currentUser.getId());
                    activityService.extSignUpActivity(request, currentUser);
                }
            }
        }
        Double qaScoreDB = userQaInfo.getQaScore();
        if (Objects.isNull(qaScoreDB) || qaScoreDB.intValue() == 0) {
            qaScoreDB = qaScore;
        }
        if (activityQaInfo.getNo() == 1) {//校赛
            userParticipateActivityInfo.setQaScore(qaScoreDB);
        } else if (activityQaInfo.getNo() == 2) {//省赛
            userParticipateActivityInfo.setProvinceQaScore(qaScoreDB);
        } else {//国赛
            userParticipateActivityInfo.setCountryQaScore(qaScoreDB);
        }
        UserInfoExtend userInfoExtend = userInfoExtendService.findByUserIdAndAppId(currentUser);
        if (Objects.nonNull(userInfoExtend)) {
            if (StringUtils.isNotBlank(userInfoExtend.getUniversityId())) {
                userParticipateActivityInfo.setUniversityId(userInfoExtend.getUniversityId());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getUniversityName())) {
                userParticipateActivityInfo.setUniversityName(userInfoExtend.getUniversityName());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getName())) {
                userParticipateActivityInfo.setName(userInfoExtend.getName());
            }
            if (StringUtils.isNotBlank(userInfoExtend.getMobile())) {
                userParticipateActivityInfo.setMobile(userInfoExtend.getMobile());
            }
        }
        userParticipateActivityInfo.setPassed(userQaInfo.getPassed());
        this.userParticipateActivityInfoService.saveOrUpdate(userParticipateActivityInfo);
        if (Objects.nonNull(userParticipateActivityInfo) && StringUtils.isNotBlank(userParticipateActivityInfo.getActivityChannelId())) {//渠道报名更新
            UserParticipateDistributorChannelInfo updateDistributorChannelInfo = new UserParticipateDistributorChannelInfo();
            updateDistributorChannelInfo.setId(null);
            updateDistributorChannelInfo.setUserId(userParticipateActivityInfo.getUserId());
            updateDistributorChannelInfo.setActivityId(userParticipateActivityInfo.getActivityId());
            updateDistributorChannelInfo.setQaScore(userParticipateActivityInfo.getQaScore());
            updateDistributorChannelInfo.setProvinceQaScore(userParticipateActivityInfo.getProvinceQaScore());
            updateDistributorChannelInfo.setCountryQaScore(userParticipateActivityInfo.getCountryQaScore());
            updateDistributorChannelInfo.setName(userParticipateActivityInfo.getName());
            updateDistributorChannelInfo.setMobile(userParticipateActivityInfo.getMobile());
            updateDistributorChannelInfo.setUniversityId(userParticipateActivityInfo.getUniversityId());
            updateDistributorChannelInfo.setUniversityName(userParticipateActivityInfo.getUniversityName());
            updateDistributorChannelInfo.setActivityChannelId(userParticipateActivityInfo.getActivityChannelId());
            userParticipateDistributorChannelInfoService.save(updateDistributorChannelInfo);
        }
        if (Objects.isNull(userQaInfo) || qaScore.intValue() == 0 || qaScore.intValue() < activityQaInfo.getPassQaScore().intValue()) {
            log.warn("【答题提交- 得分未通过】currentUser - > {} | qaInfoId->{} |qaScore -> {}", currentUser.getId(), qaInfoId,
                    qaScore);
            userQaScore.setTipsScore("很遗憾！暂不能获得证书");
            userQaScore.setButtonText("重新答题");
//            userQaScore.setQaErrorCount(userQaInfoScore.getQaErrorCount());
//            userQaScore.setQaRightCount(userQaInfoScore.getQaRightCount());
            userQaScore.setRestQa(Boolean.TRUE);
            return userQaScore;
        }
        userQaScore.setHasPaperCa(activityInfo.getHasPaperCa());
        userQaScore.setHasElectronicCa(activityInfo.getHasElectronicCa());
        userQaScore.setDigitalCaReceive(activityInfo.getDigitalCaReceive());
        userQaScore.setDigitalCaNoReceiveDesc(activityInfo.getDigitalCaNoReceiveDesc());
        QaRuleMatchRes qaRuleMatchRes = competitionQaInfoService.qaRuleByQaInfoId(qaInfoId, qaScore);
        String caLevelName = qaRuleMatchRes.getCaLevelName();
        log.info("【答题提交- 得分获取到证书等级】currentUser - > {} | qaInfoId->{} |qaScore -> {} | level -> {}", userId, qaInfoId,
                qaScore, caLevelName);
        UserQaLevel userQaLevel = new UserQaLevel();
        userQaLevel.setActivityQaInfoId(activityQaInfo.getId());
        userQaLevel.setQaNumber(activityQaInfo.getNo());
        userQaLevel.setQsScore(qaScore);
        userQaLevel.setLevel(caLevelName);
        if (CollectionUtils.isNotEmpty(userQaInfo.getUserQaLevelList())) {
            userQaInfo.getUserQaLevelList().add(userQaLevel);
        } else {
            userQaInfo.setUserQaLevelList(Arrays.asList(userQaLevel));
        }
        userQaInfo.setUpdatedTime(now);
        userQaInfo.setCaName(caLevelName);

        this.mongoTemplate.save(userQaInfo);

        UserQaLevel userQaLevel1 =
                userQaInfo.getUserQaLevelList().stream().max(Comparator.comparing(UserQaLevel::getQsScore)).get();
        if (Objects.nonNull(userQaLevel1)) {
            userParticipateActivityInfo.setContestCaName(userQaLevel1.getLevel());
        }


        UserCa userCa = new UserCa();
        Optional<CertificateActivityConfig> certificateActivityConfigOptional =
                userQaInfoService.getCertificateActivityConfig(5, activityQaInfo, activityInfo);
        if (certificateActivityConfigOptional.isPresent()) {
            CertificateActivityConfig certificateActivityConfig = certificateActivityConfigOptional.get();
            userCa.setCertificateActivityConfigId(certificateActivityConfig.getId());
            userCa.setCertificateName(certificateActivityConfig.getCertificateName());
            userCa.setCaType(certificateActivityConfig.getCaType());
            userQaScore.setCaType(certificateActivityConfig.getCaType());
        }
        userCa.setCaLevel(caLevelName);
        userCa.setActivityId(activityId);
        userCa.setMoneyType("3");
        userCa.setActivityName(activityInfo.getName());
        userCa.setTaskBizType("qa");
        userCa.setUserId(userId);
        userCa.setScore(qaScore);
        if (Objects.nonNull(userParticipateActivityInfo)) {
            userCa.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userCa.setUniversityName(userParticipateActivityInfo.getUniversityName());
            userCa.setName(userParticipateActivityInfo.getName());
            userCa.setMobile(userParticipateActivityInfo.getMobile());
            userCa.setGrade(userParticipateActivityInfo.getGrade());
        }
        userCa.setPlatform(currentUser.getCurrentPlatform());
        userCa.setAppId(currentUser.getAppId());
        //生成用户证书信息
        userCaService.create(userCa);
        if (activityInfo.getContestDigitalCaFee() > 0) {
            userQaScore.setDigitalCaPay(Boolean.TRUE);
        }
        userQaScore.setTipsScore("恭喜获得" + caLevelName);
//        userQaScore.setQaErrorCount(userQaInfoScore.getQaErrorCount());
//        userQaScore.setQaRightCount(userQaInfoScore.getQaRightCount());
        userQaScore.setCaLevel(caLevelName);
        userQaScore.setCaReceive(Boolean.TRUE);
        userQaScore.setDigitalCaPayDesc(activityInfo.getDigitalCaPayDesc());
        if (!userParticipateActivityInfo.checkUserInfo()) {
            userQaScore.setCaUserInfo(Boolean.TRUE);
        }
        if (!"wechat-mini".equals(currentUser.getCurrentPlatform())) {
            //记录用户答题
            UserCompetitionQaAnswer userCompetitionQa = new UserCompetitionQaAnswer();
            userCompetitionQa.setName(userParticipateActivityInfo.getName());
            userCompetitionQa.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userCompetitionQa.setUniversityName(userParticipateActivityInfo.getUniversityName());
//            userCompetitionQa.setAnswersQuestionInfoList(userAnswersQuestionInfoList);
            userCompetitionQa.setQaInfoId(qaInfoId);
            userCompetitionQa.setUserId(currentUser.getId());
            userCompetitionQa.setScore(qaScore);
            userCompetitionQa.setActivityGroupId(activityQaInfo.getActivityId());
            userCompetitionQaAnswerService.saveOrUpdate(userCompetitionQa);
        }

        if ("video".equals(activityInfo.getType())) {
            //维护变更用户流程状态
            userVideoService.updateStatusUserActivityCourse(currentUser, activityId, qaInfoId, courseStatus,
                    (courseStatus >= ActivityVideoStatusEnum.DO_THE_TITLE.getType()) ?
                            ActivityVideoStatusEnum.RECEIVE_CERTIFICATE.getType() :
                            ActivityVideoStatusEnum.DO_THE_TITLE.getType());
        }
        //增加用户分数
        UserQaRanking userQaRanking = new UserQaRanking();
        userQaRanking.setActivityId(activityQaInfo.getActivityId());
        userQaRanking.setQaInfoId(qaInfoId);
        userQaRanking.setQaNo(activityQaInfo.getNo());
        userQaRanking.setHeadImageUrl(currentUser.getAvatarUrl());
        userQaRanking.setUserId(userId);
        userQaRanking.setQaScore(qaScore);
        userQaRanking.setNickName(currentUser.getNickName());
        userQaRanking.setQaTitle(activityQaInfo.getName());
        if (Objects.nonNull(userParticipateActivityInfo)) {
            userQaRanking.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userQaRanking.setUniversityName(userParticipateActivityInfo.getUniversityName());
        }
        this.userQaRankingService.saveOrUpdate(userQaRanking);
        return userQaScore;
    }
}
